namespace ContosoUniversity.Tests
{
    using NRepository.Core.Events;
    using NRepository.Core.Query;
    using System.Collections.Generic;
    using System.Linq;
    using NUnit.Framework;

    public static class RepositoryQueryEventExtensions
    {
        public static List<IQueryStrategy> GetAggregateStrategies(this GetEntitiesRepositoryQueryEvent queryEvent)
        {
            return ((AggregateQueryStrategy)queryEvent.QueryStrategy).Aggregates.ToList();
        }

        public static List<IQueryStrategy> GetAggregateStrategies(this GetEntityRepositoryQueryEvent queryEvent)
        {
            return ((AggregateQueryStrategy)queryEvent.QueryStrategy).Aggregates.ToList();
        }

        public static IEnumerable<IQueryStrategy> GetAggregateStrategies(this RepositoryQueryEvent queryEvent) 
        {
            var aggregateStrategy = (AggregateQueryStrategy)((GetEntityRepositoryQueryEvent)queryEvent).QueryStrategy;
            return aggregateStrategy.Aggregates;
        }

        public static T GetAggregateStrategy<T>(this RepositoryQueryEvent queryEvent, int index) where T : class, IQueryStrategy
        {
            var aggregateStrategy = (AggregateQueryStrategy)((GetEntityRepositoryQueryEvent)queryEvent).QueryStrategy;
            return aggregateStrategy.Aggregates.ToList()[index] as T;
        }

        public static void ExpectedStrategies(this SimpleRepositoryQueryEvent queryEvent, params IQueryStrategy[] strategiesParams)
        {
            var expectedStrategies = strategiesParams.ToList();
            var allQueryStartegyEvents = new List<IQueryStrategy>();

            allQueryStartegyEvents.Add((IQueryStrategy)queryEvent.SpecificationStrategy);
            if (queryEvent.QueryStrategy is AggregateQueryStrategy)
                allQueryStartegyEvents.AddRange(((AggregateQueryStrategy)queryEvent.QueryStrategy).Aggregates);
            else
                allQueryStartegyEvents.Add(queryEvent.QueryStrategy);

            // Assert
            allQueryStartegyEvents.Count().ShouldEqual(expectedStrategies.Count());
            for (int i = 0; i < expectedStrategies.Count(); i++)
            {
                var expectedStrategy = expectedStrategies[i];
                var actualStrategy = allQueryStartegyEvents[i];

                actualStrategy.GetType().ShouldEqual(expectedStrategy.GetType());
            }
        }
    }
}
